import { Select } from "@renderer/components/ui/select";
import { usePromptEditor } from "@renderer/hooks/use-prompt-editor";
import { cn } from "@renderer/lib/utils";
import {
  PRESET_PROMPT_MAP,
  PRESET_TEXT_CACHE,
} from "@shared/prompt-editor/constant";
import type { LexicalEditor } from "lexical";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import type { Key } from "react-aria-components";
import { useTranslation } from "react-i18next";
import { PromptEditor } from "./prompt-editor";
import { UPDATE_EDITOR_CONTENT_COMMAND } from "./prompt-editor/plugins/external-update-plugin";
import { createPresetMatcher } from "./utils";

interface SystemPromptTextareaProps {
  value: string | null;
  onChange: (value: string | null) => void;
}

export function SystemPromptTextarea({
  value,
  onChange,
}: SystemPromptTextareaProps) {
  const { t } = useTranslation("translation", {
    keyPrefix: "chat.tool-bar.parameters",
  });

  const { handleStateChange } = usePromptEditor(value);

  const editorRef = useRef<LexicalEditor | null>(null);

  // Use the optimized preset matcher
  const getMatchingPresetKey = useMemo(
    () => createPresetMatcher(PRESET_TEXT_CACHE),
    [],
  );

  // Memoize matching result to avoid frequent recalculation
  const matchingPresetKey = useMemo(() => {
    return getMatchingPresetKey(value);
  }, [value, getMatchingPresetKey]);

  const [selectedKey, setSelectedKey] = useState<string>(() => {
    return matchingPresetKey || (value ? "custom" : "");
  });

  const isCustom = selectedKey === "custom";

  const PRESET_SYSTEM_PROMPT = useMemo(
    () => [
      // {
      //   key: "translation-expert",
      //   text: t("system_prompt.preset-select.translation-expert"),
      // },
      {
        key: "universal-type",
        text: t("system_prompt.preset-select.universal-type"),
      },
      {
        key: "terse-and-effective-type",
        text: t("system_prompt.preset-select.terse-and-effective-type"),
      },
      {
        key: "deep-thinking-type",
        text: t("system_prompt.preset-select.deep-thinking-type"),
      },
    ],
    [t],
  );

  const handlePresetChange = useCallback(
    (key: Key | null) => {
      const keyStr = key?.toString();
      if (!keyStr || !editorRef.current) return;

      const prompt = PRESET_PROMPT_MAP.get(keyStr);
      if (!prompt) return;

      // Set selectedKey first to prevent race condition
      setSelectedKey(keyStr);
      onChange(prompt);
      editorRef.current.dispatchCommand(UPDATE_EDITOR_CONTENT_COMMAND, prompt);
    },
    [onChange],
  );

  useEffect(() => {
    if (matchingPresetKey) {
      if (selectedKey !== matchingPresetKey) setSelectedKey(matchingPresetKey);
    } else if (value?.trim()) {
      const currentPresetText = PRESET_TEXT_CACHE.get(selectedKey) || "";
      if (currentPresetText !== value) setSelectedKey("custom");
    } else {
      setSelectedKey("");
    }
  }, [value, matchingPresetKey, selectedKey]);

  return (
    <PromptEditor
      wrapperClassName={cn("max-h-[200px] min-h-[200px] overflow-y-auto")}
      label={t("system_prompt.label")}
      tips={t("system_prompt.tips")}
      isSystemPrompt
      rightNode={
        <Select
          className="min-w-[108px] max-w-fit"
          triggerClassName="rounded-[2px] max-h-8"
          items={PRESET_SYSTEM_PROMPT}
          selectedKey={isCustom ? null : selectedKey}
          onSelectionChange={handlePresetChange}
          placeholder={
            isCustom
              ? t("system_prompt.preset-select.custom")
              : t("system_prompt.preset-select.placeholder")
          }
          aria-label={t("system_prompt.preset-select.placeholder")}
        />
      }
      canReset
      value={value}
      onChange={(newValue: string) => handleStateChange(newValue, onChange)}
      onEditorReady={(editor) => {
        editorRef.current = editor;
      }}
    />
  );
}
